#pragma once
namespace graph
{
    namespace details
    {
    
    }
struct graph_view_t
{
   //graph_view_t(graph_ptr_t graph_ptr)
   //  :  graph_ptr_(graph_ptr)
   //{}
   graph_view_t(graph_t* graph)
      :  graph_ptr_(graph)
   {}
   virtual bool vertex_predicate(vertex_t const & v) const = 0;
   virtual bool edge_predicate(edge_t const & e) const = 0;
   vertex_t const & operator [] (size_t idx) const;
   vertex_t& operator [] (size_t idx);
   vertex_t const & get_vertex_by_id(size_t idx) const;
   vertex_t& get_vertex_by_id(size_t idx);
   bool get_nearest_vertex(point_t p, vertex_id_t& result) const;   
   bool get_nearest_vertices(point_t p, std::vector<vertex_id_t> & result) const;
   bool get_nearest_edges(point_t p, std::vector<edge_t> & result) const;
    
   graph_t& get_graph() const
   {
       return *graph_ptr_;
   }     
private:
    //graph_ptr_t graph_ptr_;
    graph_t* graph_ptr_;
};
typedef boost::shared_ptr<graph_view_t> graph_view_ptr_t;
struct all_way_view_t: graph_view_t
{
    //all_way_view_t(graph_ptr_t graph_ptr)
    //  :  graph_view_t(graph_ptr)
    //{}
    all_way_view_t(graph_t* graph)
       :   graph_view_t(graph)
    {}
    virtual bool vertex_predicate(vertex_t const & v) const
    {
        return true;
    }
    virtual bool edge_predicate(edge_t const & e) const
    {
        return true;
    }
};
struct motor_way_view_t: graph_view_t
{
   //motor_way_view_t(graph_ptr_t graph_ptr)
   //   :  graph_view_t(graph_ptr)
   //{}
   motor_way_view_t(graph_t* graph)
      :   graph_view_t(graph)
   {}  
  virtual bool vertex_predicate(vertex_t const & v) const
   {
      vertex_edge_types_t types = v.get_edges_types();
      return ((types.first & 0xfe) || (types.second & 0x3));
   }
   virtual bool edge_predicate(edge_t const & e) const
   {   
      if (e.get_highway() >= 1 && e.get_highway() <= 9)
         return true;
      else
         return false;
   }
};
struct bicycle_view_t: graph_view_t
{
   //bicycle_view_t(graph_ptr_t graph_ptr)
   //   :  graph_view_t(graph_ptr)
   //{}
   bicycle_view_t(graph_t* graph)
      :   graph_view_t(graph)
   {}
   virtual bool vertex_predicate(vertex_t const & v) const
   {
      vertex_edge_types_t types = v.get_edges_types();
      return ((types.first & 0xfc) || (types.second & 0x35));
   }
   virtual bool edge_predicate(edge_t const & e) const
   {
      if ( (e.get_highway() >= 2 && e.get_highway() <= 9) ||
           (e.get_highway() == 11)||
           (e.get_highway() == 13))
         return true;
      else
         return false;
   }
};

struct foot_way_view_t: graph_view_t
{
   //foot_way_view_t(graph_ptr_t graph_ptr)
   //   :  graph_view_t(graph_ptr)
   //{}
   foot_way_view_t(graph_t* graph)
      :   graph_view_t(graph)
   {}
   virtual bool vertex_predicate(vertex_t const & v) const
   {
      vertex_edge_types_t types = v.get_edges_types();
      return ((types.first & 0xfc) || (types.second & 0x79));
   }
   virtual bool edge_predicate(edge_t const & e) const
   {
      if ( (e.get_highway() >= 2 && e.get_highway() <= 11) 
           || (e.get_highway() == 14))
         return true;
      else
         return false;
   }
};
}
